package com.github.prontera.service;

import java.time.OffsetDateTime;
import java.util.List;

import com.github.prontera.model.IdentityDomain;
import com.github.prontera.persistence.CrudMapper;
import com.github.prontera.util.Page;
import com.google.common.base.Preconditions;

/**
 * 支持泛型注入的CrudService的默认实现
 *
 * @author Alex
 */
public class CrudServiceImpl<T extends IdentityDomain> implements CrudService<T> {

	protected final CrudMapper<T> mapper;

	public CrudServiceImpl(CrudMapper<T> mapper) {
		this.mapper = mapper;
	}

	@Override
	public T get(Long id) {
		Preconditions.checkNotNull(id, "id of id should not be NULL");
		return mapper.get(id);
	}

	@Override
	public int insert(T entity) {
		Preconditions.checkNotNull(entity, "persisting entity should not be NULL");
		initializeOffsetDateTime(entity);
		return mapper.insert(entity);
	}
	
	@Override
	public int insertBatch(List<T> records) {
		Preconditions.checkNotNull(records, "persisting entity should not be NULL");
		if(records!=null&&records.size()>0){
			for (T t : records) {
				initializeOffsetDateTime(t);
			}
		}
		return mapper.insertBatch(records);
	}

	@Override
	public int update(T entity) {
		Preconditions.checkNotNull(entity, "entity in updating should not be NULL");
		entity.setUpdateTime(OffsetDateTime.now());
		return mapper.update(entity);
	}

	@Override
	public int remove(T entity) {
		Preconditions.checkNotNull(entity, "entity in updating should not be NULL");
		Preconditions.checkNotNull(entity.getId(), "type of id should not be NULL");
		return mapper.remove(entity);
	}

	private void initializeOffsetDateTime(T entity) {
		entity.setCreateTime(OffsetDateTime.now());
		if (entity.getUpdateTime() == null) {
			entity.setUpdateTime(IdentityDomain.DEFAULT_DATE_TIME);
		}
		if (entity.getDeleteTime() == null) {
			entity.setDeleteTime(IdentityDomain.DEFAULT_DATE_TIME);
		}
	}

	@Override
	public List<T> find(T entity) {
		return mapper.find(entity);
	}

	@Override
	public long count(T entity) {
		return mapper.count(entity);
	}

	@Override
	public Page<T> page(T entity) {
		long count = mapper.count(entity);
		if(entity.getPageSize()==null||entity.getPageSize()<2||entity.getPageSize()>100){
			 entity.setPageSize(10);
		}
		if(entity.getPageIndex()==null){
			 entity.setPageIndex(1);
		}
		Page<T> page = new Page<T>(entity.getPageIndex(), entity.getPageSize());
		page.setData(mapper.find(entity));
		page.setTotalCount(count);
		return page;
	}

	@Override
	public T findOne(T entity) {
		entity.setPageSize(1);
		entity.setLimitStart(0);
		entity.setLimitEnd(1);
		List<T> datas = mapper.find(entity);
		if (datas != null && datas.size() > 0) {
			return datas.get(0);
		}
		return null;
	}

}
